/**
 * Copyright (C), 2018-2018, 河北东软有限公司
 * FileName: DruidConfiguration
 * Author:   fqq
 * Date:     2018/4/26 11:08
 * Description: 开启Druid监控功能
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package pers.fqq.dlfd;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.sql.SQLException;
import javax.sql.DataSource;
import java.util.Arrays;

/**
 * 〈一句话功能简述〉<br> 
 * 〈开启Druid监控功能〉
 *
 * @author fqq
 * @create 2018/4/26
 * @since 1.0.0
 */
@Configuration
public class DruidConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);
    private static final String DB_PREFIX = "spring.datasource";

    @ConfigurationProperties(prefix = DB_PREFIX)
    @Data
    class IDataSourceProperties {
        @Value("${spring.datasource.url}")
        private String url;

        @Value("${spring.datasource.username}")
        private String username;

        @Value("${spring.datasource.password}")
        private String password;

        @Value("${spring.datasource.driverClassName}")
        private String driverClassName;

        @Value("${spring.datasource.initialSize}")
        private int initialSize;

        @Value("${spring.datasource.minIdle}")
        private int minIdle;

        @Value("${spring.datasource.maxActive}")
        private int maxActive;

        @Value("${spring.datasource.maxWait}")
        private int maxWait;

        @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
        private int timeBetweenEvictionRunsMillis;

        @Value("${spring.datasource.minEvictableIdleTimeMillis}")
        private int minEvictableIdleTimeMillis;

        @Value("${spring.datasource.validationQuery}")
        private String validationQuery;

        @Value("${spring.datasource.testWhileIdle}")
        private boolean testWhileIdle;

        @Value("${spring.datasource.testOnBorrow}")
        private boolean testOnBorrow;

        @Value("${spring.datasource.testOnReturn}")
        private boolean testOnReturn;

        @Value("${spring.datasource.poolPreparedStatements}")
        private boolean poolPreparedStatements;

        @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
        private int maxPoolPreparedStatementPerConnectionSize;

        @Value("${spring.datasource.filters}")
        private String filters;

        @Value("{spring.datasource.connectionProperties}")
        private String connectionProperties;

        @Bean
        public DataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);

            //configuration
            datasource.setInitialSize(initialSize);
            datasource.setMinIdle(minIdle);
            datasource.setMaxActive(maxActive);
            datasource.setMaxWait(maxWait);
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(testWhileIdle);
            datasource.setTestOnBorrow(testOnBorrow);
            datasource.setTestOnReturn(testOnReturn);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
            try {
                datasource.setFilters(filters);
            } catch (SQLException e) {
                System.err.println("druid configuration initialization filter: " + e);
            }
            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }

    }
    /**
     * 注册DruidServlet
     * @return
     */
    @Bean
    public ServletRegistrationBean druidServlet() {

//        return new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
        servletRegistrationBean.setServlet(new StatViewServlet());
        servletRegistrationBean.setUrlMappings(Arrays.asList("/druid/*"));
//		servletRegistrationBean.addInitParameter("allow", "192.168.16.110,127.0.0.1");// IP白名单 (没有配置或者为空，则允许所有访问)
//		servletRegistrationBean.addInitParameter("deny", "192.168.16.111/24");// IP黑名单 (存在共同时，deny优先于allow)
        servletRegistrationBean.addInitParameter("loginUsername", "fqq");// 用户名
        servletRegistrationBean.addInitParameter("loginPassword", "fqq");// 密码
        servletRegistrationBean.addInitParameter("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能(经测试，按钮还有，不过功能屏蔽了)
        return servletRegistrationBean;
    }

    /**
     * 配置Druid过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean druidStatFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

}